﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Newtonsoft.Json;

namespace Metal_Archives
{
    public partial class SearchResults : PhoneApplicationPage
    {
        CommonMethods cm = new CommonMethods();
        string argType;
        string argVal;

        public SearchResults()
        {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            //Don't do anything if you're returning to the page
            if (e.NavigationMode != System.Windows.Navigation.NavigationMode.Back)
            {
                argType = this.NavigationContext.QueryString["argType"];
                argVal = this.NavigationContext.QueryString["argVal"];
                this.lblQuery.Text = "results for " + argVal;

                //Is the user connected to the internet?
                if (cm.isOnline())
                {
                    //Get data from site
                    WebClient wc = new WebClient();
                    wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
                    switch (argType)
                    {
                        case "band":
                            wc.DownloadStringAsync(new Uri("http://www.metal-archives.com/search/ajax-band-search/?field=name&query=" + argVal));
                            break;
                        case "genre":
                            wc.DownloadStringAsync(new Uri("http://www.metal-archives.com/search/ajax-band-search/?field=genre&query=" + argVal));
                            break;
                        case "lyrics":
                            wc.DownloadStringAsync(new Uri("http://www.metal-archives.com/search/ajax-band-search/?field=themes&query=" + argVal));
                            break;
                        case "album":
                            wc.DownloadStringAsync(new Uri("http://www.metal-archives.com/search/ajax-album-search/?field=title&query=" + argVal));
                            break;
                        case "song":
                            wc.DownloadStringAsync(new Uri("http://www.metal-archives.com/search/ajax-song-search/?field=title&query=" + argVal));
                            break;
                        case "artist":
                            wc.DownloadStringAsync(new Uri("http://www.metal-archives.com/search/ajax-artist-search/?field=alias&query=" + argVal));
                            break;
                        case "label":
                            wc.DownloadStringAsync(new Uri("http://www.metal-archives.com/search/ajax-label-search/?field=name&query=" + argVal));
                            break;
                    }
                }
            }
            else
            {
                this.lsbResults.SelectedIndex = -1;
            }
        }

        void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (cm.isOnlineE(e))
            {
                Results results = new Results();

                //Deserialize JSON
                try
                {
                    results = JsonConvert.DeserializeObject<Results>(e.Result);
                }
                catch
                {
                    string abc = e.Result.Substring(0, e.Result.IndexOf("sEcho") + 8) + "0" + e.Result.Substring(e.Result.IndexOf("sEcho") + 8);
                    results = JsonConvert.DeserializeObject<Results>(abc);
                }

                //Redirect if only 1 result
                if (Convert.ToInt32(results.iTotalRecords) == 1)
                {
                    switch (argType)
                    {
                        case "band":
                        case "genre":
                        case "lyrics":
                        case "artist":
                        case "label":
                            navTo(getName(results.aaData[0], false), getLink(results.aaData[0][0]));
                            break;
                        case "album":
                        case "song":
                            navTo(getName(results.aaData[0], false), getLink(results.aaData[0][1]));
                            break;
                    }
                }

                this.lblQuery.Text = results.iTotalRecords + " " + this.lblQuery.Text;

                //Need to hide the color of the selected item, but need black or white depending on OS theme choice
                string color = cm.themeFontColor();

                //Display search results
                List<Links> lsbResultsDataSource = new List<Links>();
                foreach (string[] resultHTML in results.aaData)
                {
                    Links li = new Links();
                    switch (argType)
                    {
                        case "band":
                        case "genre":
                        case "lyrics":
                        case "artist":
                        case "label":
                            li = new Links(getName(resultHTML, false), getLink(resultHTML[0]), color, getName(resultHTML, true));
                            break;
                        case "album":
                        case "song":
                            li = new Links(getName(resultHTML, false), getLink(resultHTML[1]), color, getName(resultHTML, true));
                            break;
                    }
                    lsbResultsDataSource.Add(li);
                }
                this.lsbResults.ItemsSource = lsbResultsDataSource;
            }
        }

        private void lsbResults_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if ((sender as ListBox).SelectedIndex != -1)
            {
                Links selected = (sender as ListBox).SelectedItem as Links;
                navTo(selected.linkName, selected.linkPath);
            }
        }

        string argIt(string str)
        {
            str = str.Replace("%", "%25");
            str = str.Replace("+", "%2B");
            str = str.Replace("!", "%21");
            str = str.Replace("@", "%40");
            str = str.Replace("'", "%27");
            str = str.Replace("/", "%2F");
            str = str.Replace("\\", "%5C");
            str = str.Replace(";", "%3B");
            str = str.Replace("$", "%24");
            str = str.Replace("&", "%26");
            str = str.Replace("(", "%28");
            str = str.Replace(")", "%29");
            str = str.Replace("=", "%3D");
            str = str.Replace(",", "%2C");
            str = str.Replace("?", "%3F");
            str = str.Replace("|", "%7C");
            str = str.Replace("#", "%23");
            str = str.Replace("^", "%5E");
            str = str.Replace(" ", "+");

            return str;
        }

        string getName(string[] resultHTML, bool loc)
        {
            HtmlAgilityPack.HtmlDocument band = new HtmlAgilityPack.HtmlDocument();
            string returnMe = "";

            if (!loc) //If name
            {
                if (argType != "album" && argType != "song")
                { //Show band name
                    band.LoadHtml(resultHTML[0]);
                    returnMe = band.DocumentNode.Descendants("a").First().InnerText;
                }
                else if (argType == "album")
                { //If album, show album name
                    band.LoadHtml(resultHTML[1]);
                    returnMe = band.DocumentNode.Descendants("a").First().InnerText;
                }
                else if (argType == "song") { returnMe = resultHTML[3]; } //If song, show song name
            }
            else //If display name
            {
                //Show country
                if (argType != "album" && argType != "song" && argType != "artist" && argType != "label")
                { returnMe += "country: " + resultHTML[2]; }

                //Show lyrical theme if that's what's being searched
                if (argType == "lyrics") { returnMe += "\nband: " + resultHTML[3]; }

                //Show album info if album search
                if (argType == "album")
                {
                    //Add band name on the second line
                    band.LoadHtml(resultHTML[0]);
                    returnMe += "band: " + band.DocumentNode.Descendants("a").First().InnerText;

                    //Add release type (ex. Full Release, Live, Demo, etc)
                    returnMe += "\ntype: " + resultHTML[2];

                    //Add release date
                    returnMe += "\nrelease: " + resultHTML[3].Substring(0, resultHTML[3].IndexOf("<") - 1);
                }

                //Show song info if song search
                if (argType == "song")
                {
                    //Add band name
                    band.LoadHtml(resultHTML[0]);
                    returnMe += "band: ";
                    try
                    {
                        returnMe += band.DocumentNode.Descendants("a").First().InnerText;
                    }
                    catch
                    {
                        returnMe += band.DocumentNode.Descendants("span").First().InnerText;
                    }

                    //Add album name
                    band.LoadHtml(resultHTML[1]);
                    returnMe += "\nalbum: " + band.DocumentNode.Descendants("a").First().InnerText;

                    //Add release type
                    returnMe += "\ntype: " + resultHTML[2];
                }

                //Show artist info if artist search
                if (argType == "artist")
                {
                    //Add band name
                    band.LoadHtml("<HTML>" + resultHTML[3] + "</HTML>");
                    returnMe += "band: " + band.DocumentNode.Descendants("html").First().InnerText.Replace("&nbsp;","");
                }

                //Show label info if lable search
                if (argType == "label")
                {
                    returnMe += "specialization: " + resultHTML[2];
                    returnMe += "\ncountry: " + resultHTML[1];
                }
            }

            return returnMe;
        }

        string getLink(string resultHTML)
        {
            return resultHTML.Substring(
                resultHTML.IndexOf("\"") + 1,
                resultHTML.Substring(resultHTML.IndexOf("\"") + 1).IndexOf("\"")
            );
        }

        void navTo(string name, string link)
        {
            string navTo = "";

            switch (argType)
            {
                case "band":
                case "genre":
                case "lyrics":
                    navTo = "/Band.xaml?name=" + name + "&link=" + link;
                    break;
                case "album":
                    navTo = "/Album.xaml?name=" + name + "&link=" + link;
                    break;
                case "song":
                    navTo = "/Song.xaml?name=" + name + "&albumLink=" + link;
                    break;
                case "artist":
                    navTo = "/Artist.xaml?name=" + name + "&link=" + link;
                    break;
                case "label":
                    navTo = "/Label.xaml?name=" + name + "&link=" + link;
                    break;
            }

            NavigationService.Navigate(new Uri(navTo, UriKind.Relative));
        }
    }

    public class Results
    {
        public string error { get; set; }
        public string iTotalRecords { get; set; }
        public string iTotalDisplayRecords { get; set; }
        public string sEcho { get; set; }
        public List<string[]> aaData { get; set; }
    }
}